﻿using Infrastructure.Extend;
using Infrastructure.Web;
using MyData;
using MyData.ApiDto;
using MyData.Data.Repository;
using MyData.Dto;
using MyData.Models;
using MyDomain;
using MyRepository;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace MyRepository
{
    public class VisitorRepository : RepositoryBase<Visitor>, IVisitorRepository
    {
        public bool SaveVisitor(Visitor visitor)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                if (visitor.Id == Guid.Empty)
                {
                    visitor.Id = Guid.NewGuid();
                    var mobiles = db.IQueryable<DepartMobileRL>().Where(c => c.DepartId == Guid.Empty).Select(c => c.MobileId);
                    List<SyncRL> syncRLs = new List<SyncRL>();
                    foreach (var item in mobiles)
                    {
                        SyncRL syncRL = new SyncRL()
                        {
                            Id = Guid.NewGuid(),
                            UserId = visitor.Id,
                            UserType = (int)EnumUserType.访客,
                            OperateType = (int)EnumOperateType.新增,
                            MobileId = item
                        };
                        syncRLs.Add(syncRL);
                    }
                    db.Insert(syncRLs);
                    db.Insert(visitor);
                }
                else
                {
                    var entity = db.FindEntity<Visitor>(visitor.Id);
                    if (entity.HeadUrl != visitor.HeadUrl)
                    {
                        entity.IsDelete = 0;
                        List<SyncRL> syncRLs = new List<SyncRL>();
                        var mobiles = db.IQueryable<DepartMobileRL>().Where(c => c.DepartId == Guid.Empty).Select(c => c.MobileId);
                        foreach (var item in mobiles)
                        {
                            SyncRL syncRL = new SyncRL()
                            {
                                Id = Guid.NewGuid(),
                                UserId = visitor.Id,
                                UserType = (int)EnumUserType.访客,
                                OperateType = (int)EnumOperateType.新增,
                                MobileId = item
                            };
                            syncRLs.Add(syncRL);
                        }
                        db.Insert(syncRLs);
                    }
                    entity.DepartId = visitor.DepartId;
                    entity.DepartName = visitor.DepartName;
                    entity.Company = visitor.Company;
                    entity.PhoneNum = visitor.PhoneNum;
                    entity.OwnerName = visitor.OwnerName;
                    entity.HeadUrl = visitor.HeadUrl;
                    entity.Name = visitor.Name;
                    entity.Remark = visitor.Remark;
                    entity.StartDate = visitor.StartDate;
                    entity.EndDate = visitor.EndDate;
                    db.Update(entity);
                }
                return db.Commit() > 0;
            }
        }

        public bool SaveConfirmVisitor(Visitor visitor)
        {
            using (var db = this.NewDB())
            {
                var depart = db.QueryByKey<Depart>(visitor.DepartId);
                visitor.DepartName = depart?.Name;
                db.Insert<Visitor>(visitor);
                return true;
            }
        }

        public bool DeleteVisitor(Guid Id)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                var entity = db.FindEntity<Visitor>(Id);
                var mobiles = db.IQueryable<DepartMobileRL>().Where(c => c.DepartId == entity.DepartId).Select(c => c.MobileId);
                List<SyncRL> syncRLs = new List<SyncRL>();
                foreach (var item in mobiles)
                {
                    SyncRL syncRL = new SyncRL()
                    {
                        Id = Guid.NewGuid(),
                        UserId = entity.Id,
                        UserType = (int)EnumUserType.访客,
                        OperateType = (int)EnumOperateType.删除,
                        MobileId = item
                    };
                    syncRLs.Add(syncRL);
                }
                db.Insert(syncRLs);
                if(File.Exists(AppDomain.CurrentDomain.BaseDirectory+entity.HeadUrl))
                {
                    File.Delete(AppDomain.CurrentDomain.BaseDirectory + entity.HeadUrl);
                }
              //  entity.IsDelete = 1;
                db.Delete(entity);
                return db.Commit() > 0;
            }
        }

      
        public bool VisitorConfirm(Guid Id)
        {
            using (var db = this.NewDB())
            {
                var visitor = db.QueryByKey<Visitor>(Id);
                visitor.NeedConfirm = (int)EnumNeedConfirm.否;
                //  var mobiles = db.Query<DepartMobileRL>().Where(c => c.DepartId == Guid.Empty).Select(c => c.MobileId).ToList();
              //  var mobiles = db.Query<DepartMobileRL>().Where(c => c.DepartId == visitor.DepartId).Select(c => c.MobileId).ToList();
                //List<SyncRL> syncRLs = new List<SyncRL>();
                //foreach (var item in mobiles)
                //{
                //    SyncRL syncRL = new SyncRL()
                //    {
                //        Id = Guid.NewGuid(),
                //        UserId = visitor.Id,
                //        UserType = (int)EnumUserType.访客,
                //        OperateType = (int)EnumOperateType.新增,
                //        MobileId = item
                //    };
                //    syncRLs.Add(syncRL);
                //}
                //db.InsertRange<SyncRL>(syncRLs);
                return db.Update<Visitor>(visitor) > 0;
            }
        }

        public bool DeleteVisitorOutTime()
        {
            using (var db = this.NewDB())
            {
                var visitors = db.Query<Visitor>().Where(c => (c.IsDelete ==1 && c.EndDate <= DateTime.Now)).ToList();
                var visitorsAdd = db.Query<Visitor>().Where(c => c.IsDelete == 0&&c.NeedConfirm==0 && c.StartDate >= DateTime.Now.AddMinutes(10)).ToList();
                var mobileIds = db.Query<Mobile>().ToList();
                foreach (var m in mobileIds)
                {
                    var rls = db.Query<DepartMobileRL>().Where(c => c.MobileId == m.Id).Select(c => c.DepartId).ToList();
                    var deleteVisitors = visitors.Where(c => rls.Contains(c.DepartId)).ToList();
                    foreach (var visitor in deleteVisitors)
                    {
                        SyncRL syncRL = new SyncRL()
                        {
                            Id = Guid.NewGuid(),
                            UserId = visitor.Id,
                            OperateType = (int)EnumOperateType.删除,
                            MobileId = m.Id,
                            UserType = (int)EnumUserType.访客
                        };
                        visitor.IsDelete = 2;
                        db.Update<Visitor>(visitor);
                        db.Insert<SyncRL>(syncRL);
                    }
                    var addVisitors = visitorsAdd.Where(c => rls.Contains(c.DepartId)).ToList();
                    foreach (var visitor in addVisitors)
                    {
                        SyncRL syncRL = new SyncRL()
                        {
                            Id = Guid.NewGuid(),
                            UserId = visitor.Id,
                            OperateType = (int)EnumOperateType.新增,
                            MobileId = m.Id,
                            UserType = (int)EnumUserType.访客
                        };
                        visitor.IsDelete = 1;
                        db.Update<Visitor>(visitor);
                        db.Insert<SyncRL>(syncRL);
                    }
                }
             
                var records = db.Query<AccessRecord>().Where(c => c.CreatedTime <= DateTime.Now.AddDays(-30)).ToList();
                foreach (var r in records)
                {
                    if (System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory + r.PicPath))
                    {
                        System.IO.File.Delete(AppDomain.CurrentDomain.BaseDirectory + r.PicPath);
                    }
                    db.Delete<AccessRecord>(r);
                }
              
                return true;
            }

        }


        #region 会议用户
        public bool SaveMeet(MeetUser meetUser)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                var meetId = db.IQueryable<Meet>().OrderByDescending(c => c.CreatedTime).FirstOrDefault().Id;
                meetUser.MeetId = meetId;
                if (meetUser.Id == Guid.Empty)
                {
                    meetUser.Id = Guid.NewGuid();
                    var entity = db.IQueryable<MeetUser>().ToList().FirstOrDefault(c => c.CompanyName == meetUser.CompanyName && c.UserName == meetUser.UserName);
                    if (entity != null)
                    {
                        entity.CompanyName = meetUser.CompanyName;
                        entity.Position = meetUser.Position;
                        entity.UserName = meetUser.UserName;
                        entity.PhoneNum = meetUser.PhoneNum;
                        entity.HeadUrl = meetUser.HeadUrl;
                        entity.ApplyStatus = meetUser.ApplyStatus;
                        entity.IosType = meetUser.IosType;
                        entity.Id = meetId;
                        var mobiles = db.IQueryable<Mobile>().ToList();
                        foreach (var item in mobiles)
                        {
                            var syns = new SyncRL() { Id = Guid.NewGuid(), UserId = entity.Id, MobileId = item.Id, OperateType = (int)EnumOperateType.修改 };
                            if (db.IQueryable<SyncRL>().ToList().Any(c => c.UserId == entity.Id && c.MobileId == item.Id && c.OperateType == (int)EnumOperateType.修改) == false)
                            {
                                db.Insert(syns);
                            }

                        }
                        db.Update(entity);
                    }
                    else
                    {
                        var mobiles = db.IQueryable<Mobile>().ToList();
                        foreach (var item in mobiles)
                        {
                            var syns = new SyncRL() { Id = Guid.NewGuid(), UserId = meetUser.Id, MobileId = item.Id, OperateType = (int)EnumOperateType.新增 };
                            db.Insert(syns);
                        }
                        db.Insert(meetUser);
                    }

                }
                else
                {
                    var entity = db.FindEntity<MeetUser>(meetUser.Id);
                    if (entity == null)
                    {
                        db.Insert(entity);
                    }
                    else
                    {
                        entity.CompanyName = meetUser.CompanyName;
                        entity.Position = meetUser.Position;
                        entity.UserName = meetUser.UserName;
                        entity.PhoneNum = meetUser.PhoneNum;
                        entity.HeadUrl = meetUser.HeadUrl;
                        entity.ApplyStatus = meetUser.ApplyStatus;
                        entity.IosType = meetUser.IosType;
                        db.Update(entity);
                        var mobiles = db.IQueryable<Mobile>().ToList();
                        foreach (var item in mobiles)
                        {
                            var syns = new SyncRL() { Id = Guid.NewGuid(), UserId = entity.Id, MobileId = item.Id, OperateType = (int)EnumOperateType.修改 };
                            if (db.IQueryable<SyncRL>().ToList().Any(c => c.UserId == entity.Id && c.MobileId == item.Id && c.OperateType == (int)EnumOperateType.修改) == false)
                            {
                                db.Insert(syns);
                            }
                        }
                    }

                }

                return db.Commit() > 0;
            }
        }


        public bool DeleteCompanyUser(Guid Id)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                var entity = db.FindEntity<MeetUser>(Id);
                var mobiles = db.IQueryable<Mobile>();
                foreach (var item in mobiles)
                {
                    var syns = new SyncRL() { Id = Guid.NewGuid(), UserId = Id, MobileId = item.Id, OperateType = (int)EnumOperateType.删除 };
                    db.Insert(syns);
                }
                File.Delete(AppDomain.CurrentDomain.BaseDirectory + entity.HeadUrl);
                db.Delete(entity);
                return db.Commit() > 0;
            }
        }
        public MeetUserDto GetCompany(Guid Id)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                MeetUserDto dto = new MeetUserDto();
                var entity = db.FindEntity<MeetUser>(Id);
                dto.Id = entity.Id;
                dto.CompanyName = entity.CompanyName;
                dto.Position = entity.Position;
                dto.UserName = entity.UserName;
                dto.ApplyStatus = entity.ApplyStatus;
                dto.HeadUrl = entity.HeadUrl;
                dto.PhoneNum = entity.PhoneNum;
                return dto;
            }
        }
        public PageDto<MeetUserDto> GetCompanyUser(QueryListModel query, string company, string meetId)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                var expression = ExtLinq.True<MeetUser>();
                if (!String.IsNullOrEmpty(company))
                {
                    expression = expression.And(t => t.CompanyName.Contains(company) || t.UserName.Contains(company));
                }
                if (!string.IsNullOrEmpty(meetId))
                {
                    expression = expression.And(t => t.MeetId == new Guid(meetId));
                }
                WebHelper.WriteSession("Company", db.IQueryable(expression).OrderByDescending(t => t.CreatedTime).ToList());
                var list = db.IQueryable(expression).OrderByDescending(t => t.CreatedTime).Select(c => new MeetUserDto()
                {
                    Id = c.Id,
                    CompanyName = c.CompanyName,
                    UserName = c.UserName,
                    CreatedTime = c.CreatedTime,
                    ApplyStatus = c.ApplyStatus,
                    HeadUrl = c.HeadUrl,
                    PhoneNum = c.PhoneNum,
                    Position = c.Position,
                    MeetId = c.MeetId
                }).ToList();
                foreach (var item in list)
                {
                    item.MeetName = db.FindEntity<Meet>(item.MeetId)?.MeetName;
                }
                WebHelper.WriteSession("Company", list);
                var result = list.AsQueryable().Paging(query.Limit, query.Offset);
                return result;
            }
        }
        public WelDto GetWelDto()
        {
            WelDto dto = new WelDto();
            using (var db = new RepositoryBase().BeginTrans())
            {
                var meetId = db.IQueryable<Meet>().OrderByDescending(c => c.CreatedTime).FirstOrDefault().Id;
                var meetUsers = db.IQueryable<MeetUser>().Where(c => c.MeetId == meetId).Select(c => c.Id).ToList();
                dto.Total = meetUsers.Count();
                dto.Real = db.IQueryable<AccessRecord>().Where(c => c.MobileId == Guid.Empty && c.UserId != Guid.Empty && meetUsers.Contains(c.UserId)).Select(c => c.UserId).Distinct().ToList().Count;

                dto.TimeStr = DateTime.Now.ToString("F");
                return dto;
            }
        }
        public SynsMeetUser GetSynsMeetUser(Guid mobileId)
        {
            SynsMeetUser synsMeetUser = new SynsMeetUser();
            using (var db = new RepositoryBase().BeginTrans())
            {
                var meetUsers = db.IQueryable<SyncRL>().Where(c => c.MobileId == mobileId).ToList();
                var users = db.IQueryable<UserInfo>();
                foreach (var item in meetUsers)
                {
                    if (item.OperateType == (int)EnumOperateType.新增)
                    {
                        var user = users.FirstOrDefault(c => c.Id == item.UserId);
                        if (user != null && File.Exists(System.AppDomain.CurrentDomain.BaseDirectory + user.HeadUrl))
                        {
                            synsMeetUser.AddUsers.Add(new SynsMeet()
                            {
                                UserId = user.Id,
                                UserName = user.NickName,
                                Image = GetBase64FromImage(System.AppDomain.CurrentDomain.BaseDirectory + user.HeadUrl, 0)
                            });
                        }
                    }
                    else if (item.OperateType == (int)EnumOperateType.删除)
                    {
                        synsMeetUser.DeleteIds.Add(item.UserId);
                    }
                    else if (item.OperateType == (int)EnumOperateType.修改)
                    {
                        var user = users.FirstOrDefault(c => c.Id == item.UserId);

                        if (user != null && File.Exists(System.AppDomain.CurrentDomain.BaseDirectory + user.HeadUrl))
                        {
                            synsMeetUser.UpdateUsers.Add(new SynsMeet()
                            {
                                UserId = user.Id,
                                UserName = user.NickName,
                                Image = GetBase64FromImage(System.AppDomain.CurrentDomain.BaseDirectory + user.HeadUrl, 0)
                            });
                        }

                    }
                }

                return synsMeetUser;
            }
        }


        private string GetBase64FromImage(string imagefile, int iosType)
        {
            string strbaser64 = "";
            try
            {

                Bitmap bmp = new Bitmap(imagefile);
                //if (iosType == 1)
                //{
                //    bmp.RotateFlip(RotateFlipType.Rotate90FlipX);

                //}
                MemoryStream ms = new MemoryStream();
                bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] arr = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length);
                ms.Close();
                strbaser64 = "data:image/jpeg;base64," + Convert.ToBase64String(arr);
            }
            catch (Exception)
            {
                throw new Exception("Something wrong during convert!");
            }
            return strbaser64;
        }

        #endregion
    }
}
